
/*
 * FtpView.java
 * Created on 2009-4-14, 19:29:16
 */

package ftp;
import java.io.*;
import java.lang.*;
import java.util.*;
import ftp.*;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import javax.swing.event.*;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Color;
import java.awt.Point;

import java.awt.Rectangle;

/**
 * @author 廖龙（代码）， 李清平（界面）
 */
public class FtpView extends javax.swing.JFrame {

    public boolean debug = true;

    CoreFtp ftp;

    String currentDir = "";

    String[] dirs;
    // Create a model of the dirs.
    TableModel dirsModel = new AbstractTableModel() {
        // These methods always need to be implemented.
        String[] headers = new String [] {
            "文件名", "日期", "大小", "所有者", "群组", "子项数目", "权限"
        };
        public int getColumnCount() { return 7; }
        public int getRowCount() { return dirs.length;}
        public Object getValueAt(int row, int col) {return itemAt(dirs[row], col);}
        public String getColumnName(int column) {return headers[column];}
     };
     
    private String itemAt(String data, int col){
        String[] list = data.split(" +");
        list[5] += " " + list[6] + " " + list[7];
        list[6] = list[8];
        return list[6- col];
    }
    private String nameFrom(String dirItem){
        String[] list = dirItem.split(" +");
        if (list.length == 0) return "";
        return list[list.length-1];
    }

    LinkedList<IOCell> cells;
    // Create a model of the dirs.
    TableModel cellsModel = new AbstractTableModel() {
        // These methods always need to be implemented.
        String[] headers = new String [] {
            "标题", "大小", "进度", "速度"
        };
        public int getColumnCount() { return 4; }
        public int getRowCount() { return cells.size();}
        public String getColumnName(int column) {return headers[column];}
        public Object getValueAt(int row, int col) {
            //System.out.println("itemAt()");
            IOCell cell = cells.get(row);
            if (cell == null) return null;
            switch(col){
                default:
                case 0: return cell.getTitle();
                case 1: return cell.getTotalSize();
                case 2: return cell.getRate() + "%";
                case 3: return cell.getCurrentSpeed()/1024 + "kb/s";
            }
        }
     };

     TableModelEvent dirListener;

     java.util.Timer timer;

    class RemindTask extends TimerTask {
        public void run() {
            //cellsModel.addTableModelListener(tableCells);
            //tableCells.tableChanged(new TableModelEvent(cellsModel));
            tableCells.repaint();
            //tableCells.updateUI();
            textLog.setText(ftp.getLog());
        }
    }

    /** Creates new form FtpView */
    public FtpView() {
        initComponents();
        getRootPane().setDefaultButton(buttonConnect);
        ftp = new CoreFtp();
        ftp.debug = true;
        ftp.setMode(1);
        dirs = new String[0];
        cells = new LinkedList<IOCell>();
        tableDirs.setModel(dirsModel);
        tableCells.setModel(cellsModel);
        buttonConnect.setEnabled(true);
        buttonDisconnect.setEnabled(false);
        dirListener = new TableModelEvent(dirsModel);
        timer = new java.util.Timer();
        timer.schedule(new RemindTask() , 0,300);
    }

    private void updatePath(String path) throws IOException{
        if (path == null){
            dirs = new String[0];
            currentDir = "";
        }
        else{
            ftp.cd(path);
            dirs = ftp.ls();
            currentDir = ftp.pwd() + "/";
        }
        tableDirs.tableChanged(new TableModelEvent(dirsModel));
        tableDirs.scrollRectToVisible(new Rectangle(1,1));
        tableDirs.changeSelection(0, 0, true, true);
        panelDirs.getViewport().setViewPosition(new Point(0,0));//到顶
        textLog.setSelectionStart(textLog.getText().length());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        menuBar1 = new java.awt.MenuBar();
        menu1 = new java.awt.Menu();
        menu2 = new java.awt.Menu();
        menuBar2 = new java.awt.MenuBar();
        menu3 = new java.awt.Menu();
        menu4 = new java.awt.Menu();
        jFrame1 = new javax.swing.JFrame();
        jToggleButton1 = new javax.swing.JToggleButton();
        jDialog1 = new javax.swing.JDialog();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        textUsername = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        textPassword = new javax.swing.JPasswordField();
        textHost = new javax.swing.JTextField();
        jSeparator2 = new javax.swing.JSeparator();
        buttonConnect = new javax.swing.JButton();
        buttonDisconnect = new javax.swing.JButton();
        buttonUpload = new javax.swing.JButton();
        jSeparator3 = new javax.swing.JSeparator();
        jSeparator4 = new javax.swing.JSeparator();
        jButton8 = new javax.swing.JButton();
        panelDirs = new javax.swing.JScrollPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        tableDirs = new javax.swing.JTable();
        jLabel6 = new javax.swing.JLabel();
        textPort = new javax.swing.JTextField();
        buttonDownload = new javax.swing.JButton();
        panelCells = new javax.swing.JScrollPane();
        tableCells = new javax.swing.JTable();
        buttonStart = new javax.swing.JButton();
        buttonStop = new javax.swing.JButton();
        buttonDelete = new javax.swing.JButton();
        buttonUpper = new javax.swing.JButton();
        panelLog = new javax.swing.JScrollPane();
        jScrollPane4 = new javax.swing.JScrollPane();
        textLog = new javax.swing.JTextArea();
        jMenuBar1 = new javax.swing.JMenuBar();
        menuFile = new javax.swing.JMenu();
        connectMenu = new javax.swing.JMenuItem();
        disconnectMenu = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JSeparator();
        exitMenu = new javax.swing.JMenuItem();
        meunAction = new javax.swing.JMenu();
        menuDownload = new javax.swing.JMenuItem();
        menuUpload = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        jMenuItem7 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        menuPasv = new javax.swing.JRadioButtonMenuItem();
        menuPort = new javax.swing.JRadioButtonMenuItem();

        menu1.setLabel("File");
        menuBar1.add(menu1);

        menu2.setLabel("Edit");
        menuBar1.add(menu2);

        menu3.setLabel("File");
        menuBar2.add(menu3);

        menu4.setLabel("Edit");
        menuBar2.add(menu4);

        jFrame1.setName("jFrame1"); // NOI18N

        javax.swing.GroupLayout jFrame1Layout = new javax.swing.GroupLayout(jFrame1.getContentPane());
        jFrame1.getContentPane().setLayout(jFrame1Layout);
        jFrame1Layout.setHorizontalGroup(
            jFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        jFrame1Layout.setVerticalGroup(
            jFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        jToggleButton1.setText("jToggleButton1");
        jToggleButton1.setName("jToggleButton1"); // NOI18N

        jDialog1.setName("jDialog1"); // NOI18N

        javax.swing.GroupLayout jDialog1Layout = new javax.swing.GroupLayout(jDialog1.getContentPane());
        jDialog1.getContentPane().setLayout(jDialog1Layout);
        jDialog1Layout.setHorizontalGroup(
            jDialog1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        jDialog1Layout.setVerticalGroup(
            jDialog1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        jLabel1.setText("jLabel1");
        jLabel1.setName("jLabel1"); // NOI18N

        jLabel2.setText("jLabel2");
        jLabel2.setName("jLabel2"); // NOI18N

        jLabel3.setText("地址");
        jLabel3.setName("jLabel3"); // NOI18N

        jLabel4.setText("帐号");
        jLabel4.setName("jLabel4"); // NOI18N

        textUsername.setText("anonymous");
        textUsername.setName("textUsername"); // NOI18N

        jLabel5.setText("密码");
        jLabel5.setName("jLabel5"); // NOI18N

        textPassword.setText("anonymous");
        textPassword.setName("textPassword"); // NOI18N

        textHost.setText("211.86.156.210");
        textHost.setName("textHost"); // NOI18N
        textHost.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                textHostActionPerformed(evt);
            }
        });

        jSeparator2.setName("jSeparator2"); // NOI18N

        buttonConnect.setText("连接");
        buttonConnect.setName("buttonConnect"); // NOI18N
        buttonConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonConnectActionPerformed(evt);
            }
        });

        buttonDisconnect.setText("断开");
        buttonDisconnect.setName("buttonDisconnect"); // NOI18N
        buttonDisconnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDisconnectActionPerformed(evt);
            }
        });

        buttonUpload.setText("上传");
        buttonUpload.setName("buttonUpload"); // NOI18N
        buttonUpload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonUploadActionPerformed(evt);
            }
        });

        jSeparator3.setName("jSeparator3"); // NOI18N

        jSeparator4.setName("jSeparator4"); // NOI18N

        jButton8.setText("jButton8");
        jButton8.setName("jButton8"); // NOI18N

        panelDirs.setName("panelDirs"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        tableDirs.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null}
            },
            new String [] {
                "文件名", "大小", "日期", "权限", "所有者", "群组", "类型"
            }
        ));
        tableDirs.setName("tableDirs"); // NOI18N
        tableDirs.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tableDirsMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(tableDirs);

        panelDirs.setViewportView(jScrollPane2);

        jLabel6.setText("端口");
        jLabel6.setName("jLabel6"); // NOI18N

        textPort.setText("21");
        textPort.setName("textPort"); // NOI18N

        buttonDownload.setText("下载");
        buttonDownload.setName("buttonDownload"); // NOI18N
        buttonDownload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDownloadActionPerformed(evt);
            }
        });

        panelCells.setName("panelCells"); // NOI18N

        tableCells.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tableCells.setName("tableCells"); // NOI18N
        tableCells.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                tableCellsMousePressed(evt);
            }
        });
        panelCells.setViewportView(tableCells);

        buttonStart.setText("启动传输");
        buttonStart.setName("buttonStart"); // NOI18N
        buttonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonStartActionPerformed(evt);
            }
        });

        buttonStop.setText("停止传输");
        buttonStop.setName("buttonStop"); // NOI18N
        buttonStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonStopActionPerformed(evt);
            }
        });

        buttonDelete.setText("删除传输");
        buttonDelete.setName("buttonDelete"); // NOI18N
        buttonDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDeleteActionPerformed(evt);
            }
        });

        buttonUpper.setText("上一级目录");
        buttonUpper.setName("buttonUpper"); // NOI18N
        buttonUpper.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonUpperActionPerformed(evt);
            }
        });

        panelLog.setName("panelLog"); // NOI18N

        jScrollPane4.setName("jScrollPane4"); // NOI18N

        textLog.setColumns(20);
        textLog.setRows(5);
        textLog.setName("textLog"); // NOI18N
        jScrollPane4.setViewportView(textLog);

        panelLog.setViewportView(jScrollPane4);

        jMenuBar1.setName("jMenuBar1"); // NOI18N

        menuFile.setText("文件");
        menuFile.setName("menuFile"); // NOI18N

        connectMenu.setText("连接");
        connectMenu.setName("connectMenu"); // NOI18N
        menuFile.add(connectMenu);

        disconnectMenu.setText("断开");
        disconnectMenu.setName("disconnectMenu"); // NOI18N
        menuFile.add(disconnectMenu);

        jSeparator5.setName("jSeparator5"); // NOI18N
        menuFile.add(jSeparator5);

        exitMenu.setText("退出");
        exitMenu.setName("exitMenu"); // NOI18N
        exitMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuActionPerformed(evt);
            }
        });
        menuFile.add(exitMenu);

        jMenuBar1.add(menuFile);

        meunAction.setText("动作");
        meunAction.setName("meunAction"); // NOI18N

        menuDownload.setText("下载");
        menuDownload.setName("menuDownload"); // NOI18N
        meunAction.add(menuDownload);

        menuUpload.setText("上传");
        menuUpload.setName("menuUpload"); // NOI18N
        meunAction.add(menuUpload);

        jSeparator1.setName("jSeparator1"); // NOI18N
        meunAction.add(jSeparator1);

        jMenuItem7.setText("启动");
        jMenuItem7.setName("jMenuItem7"); // NOI18N
        meunAction.add(jMenuItem7);

        jMenuItem5.setText("停止");
        jMenuItem5.setName("jMenuItem5"); // NOI18N
        meunAction.add(jMenuItem5);

        jMenuItem1.setText("删除");
        jMenuItem1.setName("jMenuItem1"); // NOI18N
        meunAction.add(jMenuItem1);

        jMenuBar1.add(meunAction);

        jMenu1.setText("设置");
        jMenu1.setName("jMenu1"); // NOI18N

        menuPasv.setSelected(true);
        menuPasv.setText("PASV被动模式传输");
        menuPasv.setName("menuPasv"); // NOI18N
        menuPasv.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuPasvActionPerformed(evt);
            }
        });
        jMenu1.add(menuPasv);

        menuPort.setText("PORT主动模式传输");
        menuPort.setName("menuPort"); // NOI18N
        menuPort.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuPortActionPerformed(evt);
            }
        });
        jMenu1.add(menuPort);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(panelDirs, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 845, Short.MAX_VALUE)
                    .addComponent(panelLog, javax.swing.GroupLayout.DEFAULT_SIZE, 845, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(buttonDownload)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(buttonUpload)
                        .addGap(18, 18, 18)
                        .addComponent(buttonStart)
                        .addGap(18, 18, 18)
                        .addComponent(buttonStop)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(buttonDelete)
                        .addGap(99, 99, 99)
                        .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonUpper))
                    .addComponent(jSeparator4, javax.swing.GroupLayout.DEFAULT_SIZE, 845, Short.MAX_VALUE)
                    .addComponent(panelCells, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 845, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(textHost, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(textPort, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel4)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(textUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jLabel5)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(textPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(buttonConnect)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(buttonDisconnect))
                            .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 635, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(buttonUpper)
                        .addComponent(buttonDownload)
                        .addComponent(buttonUpload)
                        .addComponent(buttonStart)
                        .addComponent(buttonStop)
                        .addComponent(buttonDelete)))
                .addGap(8, 8, 8)
                .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)
                    .addComponent(textPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(textUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5)
                    .addComponent(textPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(buttonConnect)
                    .addComponent(buttonDisconnect)
                    .addComponent(textHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(4, 4, 4)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(panelDirs, javax.swing.GroupLayout.DEFAULT_SIZE, 207, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(panelCells, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(panelLog, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(12, 12, 12))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void buttonConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonConnectActionPerformed
        ftp.setHost(textHost.getText());
        ftp.setPort(Integer.valueOf(textPort.getText()).intValue());
        ftp.setUsername(textUsername.getText());
        ftp.setPassword(new String(textPassword.getPassword()));
        try{
            ftp.connect();
            buttonConnect.setEnabled(false);
            buttonDisconnect.setEnabled(true);
            updatePath("/");
            //tableDirs.tableChanged(new TableModelEvent(dirsModel));
        }catch(IOException e){
            System.out.println(e);
        }
 }//GEN-LAST:event_buttonConnectActionPerformed

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened

    }//GEN-LAST:event_formWindowOpened

    private void buttonDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDisconnectActionPerformed
        try{
            ftp.disconnect();
            updatePath(null);
        }catch(IOException e){
            System.out.println(e);
        }
        buttonConnect.setEnabled(true);
        buttonDisconnect.setEnabled(false);
        //tableDirs.tableChanged(new TableModelEvent(dirsModel));
    }//GEN-LAST:event_buttonDisconnectActionPerformed

    private void textHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_textHostActionPerformed

    }//GEN-LAST:event_textHostActionPerformed

    private void buttonUploadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonUploadActionPerformed
        JFileChooser chooser = new JFileChooser();
        File file;
        int returnVal = chooser.showOpenDialog(this);
        if(returnVal == JFileChooser.APPROVE_OPTION)
            file = chooser.getSelectedFile();
        else
            return;
        if (debug) System.out.println("try to upload" + file.getAbsolutePath());
        try{
            cells.add(ftp.upload(currentDir + file.getName(), file.getPath()));
        }catch(IOException e){
            System.out.println(e);
        }
}//GEN-LAST:event_buttonUploadActionPerformed

    private void buttonDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDownloadActionPerformed
        int[] rows = tableDirs.getSelectedRows();
        if (rows.length == 0) return;
        JFileChooser chooser = new JFileChooser();
        for (int i= 0; i < rows.length; i ++){
            String remoteName = nameFrom(dirs[rows[i]]);
            String local = "";
            chooser.setSelectedFile(new File("./" + remoteName));
            int returnVal = chooser.showOpenDialog(this);
            if(returnVal == JFileChooser.APPROVE_OPTION)
                local = chooser.getSelectedFile().getPath();
            else
                continue;
            if (debug) System.out.println("try to download" + remoteName);
            try{
                cells.add(ftp.download(currentDir + remoteName, local));
            }catch(IOException e){
                System.out.println(e);
            }catch(NullPointerException e){
                System.out.println(e);
                System.out.println("cells.size() = " + cells.size());
            }finally{
                tableCells.tableChanged(new TableModelEvent(cellsModel));
            }
        }
    }//GEN-LAST:event_buttonDownloadActionPerformed

    private void exitMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuActionPerformed

    private void tableDirsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableDirsMouseClicked
        int c = evt.getClickCount();
        if (c < 2) return ;
        int row = tableDirs.getSelectedRow();
        try{
            updatePath(currentDir + nameFrom(dirs[row]));
        }catch (IOException e){
            System.out.println("unable to cd " + dirs[row]);
        }
    }//GEN-LAST:event_tableDirsMouseClicked

    private void menuPasvActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPasvActionPerformed
        menuPort.setSelected(false);
        menuPasv.setSelected(true);
        ftp.setMode(1);
}//GEN-LAST:event_menuPasvActionPerformed

    private void menuPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPortActionPerformed
        menuPort.setSelected(true);
        menuPasv.setSelected(false);
        ftp.setMode(0);
    }//GEN-LAST:event_menuPortActionPerformed

    private void tableCellsMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableCellsMousePressed

    }//GEN-LAST:event_tableCellsMousePressed

    private void buttonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStartActionPerformed
        int[] rows = tableCells.getSelectedRows();
        for (int i= 0; i < rows.length; i ++){
            if (debug) System.out.println("ioStart() at " + i);
            cells.get(rows[i]).ioStart();
            //cells.get(rows[i]).notify();
        }
    }//GEN-LAST:event_buttonStartActionPerformed

    private void buttonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStopActionPerformed
        int[] rows = tableCells.getSelectedRows();
        for (int i= 0; i < rows.length; i ++){
            if (debug) System.out.println("ioStop() at " + i);
            cells.get(rows[i]).ioStop();
        }
    }//GEN-LAST:event_buttonStopActionPerformed

    private void buttonDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeleteActionPerformed
        int[] rows = tableCells.getSelectedRows();
        for (int i= 0; i < rows.length; i ++){
            if (debug) System.out.println("ioDelete() at " + i);
            IOCell cell = cells.remove(rows[i]);
            cell.ioDelete();
            //delete cell;
            tableCells.tableChanged(new TableModelEvent(cellsModel));
        }
    }//GEN-LAST:event_buttonDeleteActionPerformed

    private void buttonUpperActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonUpperActionPerformed
        try{
            updatePath("..");
        }catch(IOException e){}
    }//GEN-LAST:event_buttonUpperActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FtpView().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonConnect;
    private javax.swing.JButton buttonDelete;
    private javax.swing.JButton buttonDisconnect;
    private javax.swing.JButton buttonDownload;
    private javax.swing.JButton buttonStart;
    private javax.swing.JButton buttonStop;
    private javax.swing.JButton buttonUpload;
    private javax.swing.JButton buttonUpper;
    private javax.swing.JMenuItem connectMenu;
    private javax.swing.JMenuItem disconnectMenu;
    private javax.swing.JMenuItem exitMenu;
    private javax.swing.JButton jButton8;
    private javax.swing.JDialog jDialog1;
    private javax.swing.JFrame jFrame1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem5;
    private javax.swing.JMenuItem jMenuItem7;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JSeparator jSeparator5;
    private javax.swing.JToggleButton jToggleButton1;
    private java.awt.Menu menu1;
    private java.awt.Menu menu2;
    private java.awt.Menu menu3;
    private java.awt.Menu menu4;
    private java.awt.MenuBar menuBar1;
    private java.awt.MenuBar menuBar2;
    private javax.swing.JMenuItem menuDownload;
    private javax.swing.JMenu menuFile;
    private javax.swing.JRadioButtonMenuItem menuPasv;
    private javax.swing.JRadioButtonMenuItem menuPort;
    private javax.swing.JMenuItem menuUpload;
    private javax.swing.JMenu meunAction;
    private javax.swing.JScrollPane panelCells;
    private javax.swing.JScrollPane panelDirs;
    private javax.swing.JScrollPane panelLog;
    private javax.swing.JTable tableCells;
    private javax.swing.JTable tableDirs;
    private javax.swing.JTextField textHost;
    private javax.swing.JTextArea textLog;
    private javax.swing.JPasswordField textPassword;
    private javax.swing.JTextField textPort;
    private javax.swing.JTextField textUsername;
    // End of variables declaration//GEN-END:variables

}
